﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rotempco.Core.Updater.Objects;
using System.IO;
using System.Windows;
using Rotempco.Core.Logic;

namespace Rotempco.Core.Updater.Logic
{
    public class UpdaterLogic
    {
        public static void UpdateCore(string basePath, RotempcoSettings projectSettings, string sourceDirectory, string destinationDirectory, List<string> directoriesSelected, string projectName)
        {
            List<string> safeList = SerializerLogic.Deserialize(projectSettings.GetValue("@SafeList")) as List<string>;
            Cleanup(basePath, projectSettings, safeList, sourceDirectory, destinationDirectory, directoriesSelected);
            Update(basePath, projectSettings, safeList, sourceDirectory, destinationDirectory, directoriesSelected, projectName);
        }

        private static void Cleanup(string basePath, RotempcoSettings projectSettings, List<string> safeList, string sourceDirectory, string destinationDirectory, List<string> directoriesSelected)
        {
            foreach (string directory in directoriesSelected)
            {
                if (Directory.Exists(destinationDirectory + @"\" + directory))
                {
                    Cleanup(basePath, projectSettings, safeList, sourceDirectory + @"\" + directory + @"\", destinationDirectory + @"\" + directory + @"\");
                }
            }
        }

        private static void Cleanup(string basePath, RotempcoSettings projectSettings, List<string> safeList, string sourceDirectory, string destinationDictionary)
        {
            FileInfo[] sourceFiles = new DirectoryInfo(sourceDirectory).GetFiles();
            FileInfo[] destinationFiles = new DirectoryInfo(destinationDictionary).GetFiles();

            foreach (FileInfo destinationFile in destinationFiles)
            {
                FileInfo sourceFile = (from s in sourceFiles where s.Name == destinationFile.Name select s).FirstOrDefault();

                if (sourceFile == null)
                {
                    if (!SafeListContains(basePath, safeList, destinationFile.FullName))
                    {
                        string relativePath = destinationFile.FullName.Substring(basePath.Count());

                        MessageBoxResult messageBoxResult = MessageBox.Show("Do you wish to add [" + relativePath + "] to the safe list (Yes) or Delete it (No) or Skip it (Cancel)", "Save file", MessageBoxButton.YesNoCancel);
                        if (messageBoxResult == MessageBoxResult.Yes)
                        {
                            safeList.Add(relativePath);
                            projectSettings.SetKey("@SafeList", SerializerLogic.SerializeObject(safeList));
                        }
                        else if (messageBoxResult == MessageBoxResult.No)
                        {
                            destinationFile.Delete();
                        }
                    }
                }
            }

            foreach (DirectoryInfo directory in new DirectoryInfo(destinationDictionary).GetDirectories())
            {
                if (directory.Name.Equals(".svn", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("obj", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("bin", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("properties", StringComparison.CurrentCultureIgnoreCase)
                    )
                    continue;

                if (!Directory.Exists(sourceDirectory + @"\" + directory.Name))
                {
                    if ( !SafeListContains(basePath, safeList, destinationDictionary + @"\" + directory.Name))
                    {
                        string relativePath = directory.FullName.Substring(basePath.Count());

                        MessageBoxResult messageBoxResult = MessageBox.Show("Do you wish to add [" + relativePath + "] to the safe list (Yes) or Delete it (No) or Skip it (Cancel)", "Save file", MessageBoxButton.YesNoCancel);
                        if (messageBoxResult == MessageBoxResult.Yes)
                        {
                            safeList.Add(relativePath);
                            projectSettings.SetKey("@SafeList", SerializerLogic.SerializeObject(safeList));
                        }
                        else if (messageBoxResult == MessageBoxResult.No)
                        {
                            directory.Delete(true);
                        }
                    }
                }
                else
                    Cleanup(basePath, projectSettings, safeList, sourceDirectory + @"\" + directory.Name, directory.FullName);
            }
        }

        private static bool SafeListContains(string basePath, List<string> safeList, string path)
        {
            if (safeList == null)
                return false;

            string relativePath = path.Substring(basePath.Count());
            relativePath = relativePath.Replace(@"\\", @"\");

            return (from s in safeList
                    where s.Equals(relativePath, StringComparison.CurrentCultureIgnoreCase)
                    select s).FirstOrDefault() != null;
        }

        private static void Update(string basePath, RotempcoSettings projectSettings, List<string> safeList, string sourceDirectory, string destinationDirectory, List<string> directoriesSelected, string projectName)
        {
            foreach (string directory in directoriesSelected)
            {
                Update(basePath, projectSettings, safeList, sourceDirectory + @"\" + directory + @"\", destinationDirectory + @"\" + directory + @"\", projectName);
            }
        }
                
        private static void Update(string basePath, RotempcoSettings projectSettings, List<string> safeList, string sourceDirectory, string destinationDictionary, string projectName)
        {
            FileInfo[] sourceFiles = new DirectoryInfo(sourceDirectory).GetFiles();
            FileInfo[] destinationFiles = new FileInfo[0];

            if (Directory.Exists(destinationDictionary))
                destinationFiles = new DirectoryInfo(destinationDictionary).GetFiles();
            else
                Directory.CreateDirectory(destinationDictionary);

            foreach (FileInfo sourceFile in sourceFiles)
            {
                if (!File.Exists(destinationDictionary + @"\" + sourceFile.Name) || !SafeListContains(basePath, safeList, destinationDictionary + @"\" + sourceFile.Name))
                    ConvertFile(sourceFile, destinationDictionary + @"\" + sourceFile.Name, projectName);
            }

            foreach (DirectoryInfo directory in new DirectoryInfo(sourceDirectory).GetDirectories())
            {
                if (directory.Name.Equals(".svn", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("obj", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("bin", StringComparison.CurrentCultureIgnoreCase) ||
                    directory.Name.Equals("properties", StringComparison.CurrentCultureIgnoreCase))
                    continue;

                if (!Directory.Exists(destinationDictionary + @"\" + directory.Name))
                    Directory.CreateDirectory(destinationDictionary + @"\" + directory.Name);
                
                Update(basePath, projectSettings, safeList, directory.FullName, destinationDictionary + @"\" + directory.Name, projectName);
            }
        }

        private static void ConvertFile(FileInfo sourceFile, string destinationFileName, string projectName)
        {
            string text = File.ReadAllText(sourceFile.FullName, Encoding.Default);

            File.WriteAllText(destinationFileName, text.Replace("Rotempco.Core", projectName), Encoding.UTF8);
        }
    }
}
